package unamur.iodass.communication;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;

import org.apache.log4j.Logger;
import unamur.iodass.accountancy.Accountancy;
import unamur.iodass.catalog.CatalogHandler;
import unamur.iodass.communication.messages.*;
import unamur.iodass.data.SoldBooks;
import unamur.iodass.host.HostHandler;



public class Server {

	private static final Logger logger = Logger.getLogger(Server.class);

	private volatile boolean started;

	Server() {
		// Nothing
	}

	/**
	 * Start the listener.
	 */
	void start() {
		started = true;
		Thread daemon = new Thread(new Daemon());
		daemon.start();
	}

	/**
	 * Stop the listener
	 */
	void stop() {
		started = false;
	}

	// Represent the daemon lunched when this is started
	private class Daemon implements Runnable {

		@Override
		public void run() {
			try {
				ServerSocket serverSocket = new ServerSocket(Communication.BOOKSTORE_PORT);
				while (started) {
					try {
						Socket socket = serverSocket.accept();
						new Thread(new Slave(socket)).start();
					} catch (SocketTimeoutException e) {
						// do nothing
					} catch (IOException e) {
						logger.error(e);
					}
				}
				serverSocket.close();
			} catch (IOException e) {
				logger.error(e);
			}
			logger.info("daemon stopped");
		}

	}

	// Represent a slave lunched by the daemon
	private class Slave implements Runnable {

		private Socket socket;

		private Slave(Socket socket) {
			this.socket = socket;
		}

		@Override
		public void run() {
			try {
				try {
					ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
					Message message = (Message) ois.readObject();

					if (message instanceof LibraryRequest) {
						LibraryRequest libraryRequest = (LibraryRequest) message;

						if (libraryRequest.getQuery().equals("GETCATALOG")) {
							logger.info("BookStore side - GETCATALOG ");
							CatalogHandler.getInstance().sendCatalogToServer();

						} else if (libraryRequest.getQuery().equals("STARTAUCTION")) {
							logger.info("BookStore side - STARTAUCTION ");
							HostHandler.getInstance().newDeal(libraryRequest.getIsbn(), libraryRequest.getMinimum(), libraryRequest.getBookStores());

						}
					} else if (message instanceof BookDeal) {
						BookDeal bookdeal = (BookDeal) message;

						if (bookdeal.getBookStore() == null) {
							Accountancy.getInstance().handleBookDeal(bookdeal);
						} else {
							HostHandler.getInstance().handleBookDeal(bookdeal);
						}
					} else if (message instanceof ContratBookStore) {
						ContratBookStore contrat = (ContratBookStore) message;
						
						SoldBooks.getInstance().addContratBookStore(contrat);
					} else if (message instanceof CancelDeliver) {
						CancelDeliver cancelDeliver = (CancelDeliver) message;
						
						SoldBooks.getInstance().remodeContratBookStore(cancelDeliver);
					} 


				} catch (ClassNotFoundException e) {
					logger.error(e);
				} catch (ClassCastException e) {
					logger.error(e);
				}
				socket.close();
			} catch (IOException e) {
				logger.error(e);
			}
		}

	}

}

